package com.pci.netty.util;

import cn.hutool.core.codec.BCD;
import cn.hutool.crypto.digest.DigestUtil;
import com.pci.netty.enums.MessageTypeEnum;
import com.pci.netty.enums.ReplyMarkEnum;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;

public class RequestUtils {
    /**
     * 发送心跳
     *
     * @param ctx
     */
    public static void heartbeat(ChannelHandlerContext ctx) {
        send(MessageTypeEnum.HEARTBEAT, "19012201", "18012201", null, ctx);
    }

    /**
     * 发送消息
     *
     * @param messageTypeEnum 消息类型
     * @param requestSeq       发起方标识码（由线路+车站+设备类型+设备ID组成，8位）
     * @param content         消息内容
     * @param channelFuture
     */
    public static void sendData(MessageTypeEnum messageTypeEnum, String requestSeq, String responseSeq, String content, ChannelFuture channelFuture) {
        ByteBuf request = build(messageTypeEnum, requestSeq,responseSeq, content);
        channelFuture.channel().writeAndFlush(request);

    }
    /**
     * 发送消息
     *
     * @param messageTypeEnum 消息类型
     * @param requestSeq      发起方标识码（由线路+车站+设备类型+设备ID组成，8位）
     * @param content         消息内容
     * @param ctx
     */
    private static void send(MessageTypeEnum messageTypeEnum, String requestSeq, String responseSeq, String content, ChannelHandlerContext ctx) {
        ByteBuf request = build(messageTypeEnum, requestSeq, responseSeq, content);
        ctx.writeAndFlush(request);
    }

    private static ByteBuf build(MessageTypeEnum messageTypeEnum, String requestSeq, String responseSeq, String content) {
        if (StringUtils.isBlank(requestSeq)) {
            throw new RuntimeException("发起方标识码不能为空");
        }
        if (requestSeq.length() != 8) {
            throw new RuntimeException("发起方标识码长度为8位");
        }
        if (StringUtils.isBlank(responseSeq)) {
            throw new RuntimeException("接收方标识码不能为空");
        }
        if (responseSeq.length() != 8) {
            throw new RuntimeException("接收方标识码长度为8位");
        }
        ByteBuf byteBuf = Unpooled.buffer(16);
        byteBuf.writeBytes(BCD.strToBcd(String.valueOf(messageTypeEnum.getCode())));
        byteBuf.writeBytes(BCD.strToBcd(requestSeq));
        byteBuf.writeBytes(BCD.strToBcd(responseSeq));
        byteBuf.writeInt(RandomUtils.nextInt());
        byteBuf.writeByte(ReplyMarkEnum.REQUEST.getCode());
        byteBuf.writeByte((byte) 0);

        byte[] head = new byte[16], md5;
        byteBuf.readBytes(head);

        if (content != null) {
            byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8);
            byte[] encrypt = AESUtils.encrypt(contentBytes);
            byte[] data = new byte[16 + encrypt.length];
            System.arraycopy(head, 0, data, 0, 16);
            System.arraycopy(encrypt, 0, data, 16, encrypt.length);
            md5 = DigestUtil.md5(data);
            byteBuf.writeBytes(data);
        } else {
            md5 = DigestUtil.md5(head);
            byteBuf.writeBytes(head);
        }
        byteBuf.writeBytes(md5);
        return byteBuf;
    }


}
